const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const { expressjwt:jwt } = require('express-jwt');
const md5 = require("md5");
const session = require('express-session')

// 捕获异步错误
require("express-async-errors")
// 默认读取项目根目录下的 .env 环境变量文件
require('dotenv').config()
// 引入数据库连接
require('./dao/config/db')
// 引入路由
const adminRouter = require('./routes/admin');
const captchaRouter = require('./routes/captcha');
const bannerRouter = require('./routes/banner');
const uploadRouter = require('./routes/upload');
const blogTypeRouter = require('./routes/blogType');
const blogRouter = require('./routes/blog');
const messageRouter = require('./routes/message');
const userRouter = require('./routes/user');
const returnSchoolRouter = require('./routes/returnSchool');
const askRouter = require('./routes/ask')

// 引入错误类
const {ForbiddenError, ServiceError, UnknownError} = require("./utils/errors");


// 创建服务器实例
const app = express();

app.use(session({
    secret: process.env.SESSION_SECRET,
    resave: true,
    saveUninitialized: true,
}))

// 使用中间件
app.use(logger('dev'));  // 控制台打印日志
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 验证 token
app.use(jwt({
    secret: md5(process.env.JWT_SECRET),
    algorithms: ['HS256']
}).unless({
    path: [
        {url: '/api/admin/login', methods: ['POST']},
        {url: '/res/captcha', methods: ['GET']},
        {url: '/api/banner', methods: ['GET']},
        {url: '/api/blogtype', methods: ['GET']},
        {url: '/api/blog', methods: ['GET']},
        {url: /\/api\/blog\/\d/, methods: ['GET']}, // 使用正则获取单篇文章接口
        {url: '/api/message', methods: ['GET', 'POST']},
        {url: '/api/comment', methods: ['GET', 'POST']},
    ]
}));

// 使用路由中间件
app.use('/api/admin', adminRouter);
app.use('/api/banner', bannerRouter);
app.use('/res/captcha', captchaRouter);
app.use('/api/upload', uploadRouter);
app.use('/api/blog', blogRouter);
app.use('/api/blogtype', blogTypeRouter);
app.use('/api/message', messageRouter);
app.use('/api/comment', messageRouter);
// 用户管理
app.use('/api/user', userRouter);
// 返校管理
app.use('/api/returnSchool', returnSchoolRouter);
// 咨询管理
app.use('/api/ask', askRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    next(createError(404));
});

// 错处处理
app.use(function (err, req, res, next) {
    if (err.name === 'UnauthorizedError') {
        res.send(new ForbiddenError("未登录，或者登录已过期").toResponseJSON())
    } else if (err instanceof ServiceError) {
        res.send(err.toResponseJSON())
    } else {
        res.send(new UnknownError().toResponseJSON())
    }
});


module.exports = app;
